package com.yanqu.road.server.gameplayer.module.activity.chefduel;

import com.yanqu.road.dao.impl.activity.chefduel.ChefDuelPhase1UserDataDaoImpl;
import com.yanqu.road.entity.autodata.chefduel.ChefDuelPhase1UserData;
import com.yanqu.road.entity.autodata.chefduel.config.ChefDuel1DrawModifyConfig;
import com.yanqu.road.entity.autodata.chefduel.config.ChefDuel1LevelConfig;
import com.yanqu.road.entity.autodata.chefduel.config.ChefDuel1MissionConfig;
import com.yanqu.road.entity.autodata.chefduel.config.ChefDuel1TalentConfig;
import com.yanqu.road.entity.autodata.chefduel.entity.ChefDuel1DeviceGroup;
import com.yanqu.road.entity.autodata.chefduel.entity.ChefDuel1StageData;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.chefduel.LogChefDuelPhase1DeviceGroupLevelUp;
import com.yanqu.road.entity.log.chefduel.LogChefDuelPhase1Modify;
import com.yanqu.road.entity.log.chefduel.LogChefDuelPhase1PassStage;
import com.yanqu.road.entity.log.chefduel.LogChefDuelPhase1Skill;
import com.yanqu.road.logic.activity.chefduel.ChefDuel1Config;
import com.yanqu.road.logic.helper.CalcPowerResult;
import com.yanqu.road.logic.helper.PowerHelper;
import com.yanqu.road.pb.activity.ChefDuelPhase1Proto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.logic.activity.relation.condition.arg.ChefDuel1RankArg;
import com.yanqu.road.server.logic.activity.relation.condition.arg.ChefDuel1UnlimitedRankArg;
import com.yanqu.road.server.manger.activity.ActivityMgr;

import com.yanqu.road.server.manger.activity.chefduel.ChefDuelPhase1Mgr;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 厨神对决一阶段模块
 */
public class ChefDuelPhase1Module extends GeneralModule {

    private ChefDuelPhase1UserData userData;

    private int playingStageId = -1;

    public ChefDuelPhase1Module(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        ChefDuel1Config config = ChefDuelPhase1Mgr.getConfig();
        if (config != null) {
            if (ActivityMgr.activityInShowTime(config.getActivityInfo())){
                userData = new ChefDuelPhase1UserDataDaoImpl().getChefDuelPhase1UserData(config.getActivityId(),getUserId());
            }
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        if (userData != null) {
            if (userData.isInsertOption()){
                new ChefDuelPhase1UserDataDaoImpl().add(userData);
            }else if (userData.isUpdateOption()){
                new ChefDuelPhase1UserDataDaoImpl().update(userData);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        checkAndSendData();
    }

    /**
     * 检测系统并下发数据
     */
    public void checkAndSendData(){
        syncConfig();               //同步配置
        checkInitUserData();        //检测数据初始化
        checkEnergyRecovery();      //检测体力恢复
        syncUserData();             //同步玩家数据
    }

    /**
     * 游戏结束
     */
    public int gameOver(int activityId,long coin,int stageId,int consumerNum){
        int checkCanPlayGame = checkCanPlayGame(activityId);
        if (checkCanPlayGame!=0){
            return checkCanPlayGame;
        }
        if (playingStageId < 0){
            return GameErrorCode.E_CHEF_DUEL1_GAME_STATE_ERROR;
        }
//        int stageId = playingStageId;
        if (playingStageId != stageId){
            log.error("玩家厨神争霸一阶段游戏开始和结束不是同一个关卡,userId:{},playing{},stageId:{}",getUserId(),playingStageId,stageId);
            return GameErrorCode.E_CHEF_DUEL1_GAME_STATE_ERROR;
        }

        playingStageId = -1;
        //拿关卡配置
        ChefDuel1Config config = ChefDuelPhase1Mgr.getConfig();
        ChefDuel1MissionConfig missionConfig = config.getMissionConfig(stageId);
        if(missionConfig == null){
            return GameErrorCode.E_CHEF_DUEL1_CONFIG_ERROR;
        }
        //看看是不是到达了积分限制 怕直接刷
        if (userData.getGrade() < missionConfig.getScoreLimit()){
            return GameErrorCode.E_CHEF_DUEL1_GRADE_NO_ENOUGH;
        }
        //拿出关卡需求分数
        int evaluate = missionConfig.getEvaluate();
        //是否之前通关过
        boolean hadPassedBefore = false;
        //拿出所有通关关卡
        Map<Integer, ChefDuel1StageData> passStages = userData.getPassStages();
        if (passStages.containsKey(stageId)){
            hadPassedBefore = true;
        }
        ChefDuelPhase1Proto.ChefDuelPhase1GameOverResp.Builder builder = ChefDuelPhase1Proto.ChefDuelPhase1GameOverResp.newBuilder();
        //如果是普通关卡
        if (missionConfig.getType() != 0){
            //分数没到 不管了
            if (coin < evaluate){
                builder.setRet(0);
                player.sendPacket(ClientProtocol.U_CHEF_DUEL1_GAME_OVER,builder);
                return 0;
            }
        }else {     //如果是极限挑战 判断一下数值 如果分数大于最大值或者人数大于最大值 那就是刷的
            if (coin > config.getUnLimitModeMaxCoin() || consumerNum > config.getUnLimitModeMaxGuest()){
                return GameErrorCode.E_CHEF_DUEL1_ARG_ERROR;
            }
        }
        //已经通关过了 更新下最高分 就直接回包吧
        if (hadPassedBefore){
            ChefDuel1StageData chefDuel1StageData = passStages.get(stageId);
            //如果
            if (chefDuel1StageData == null){
                log.error("更新玩家最高分失败,玩家数据错误,userId{},activityId{},stageId:{}",getUserId(),activityId,stageId);
            }else {
                //优先记银币数量最多的  同银币数时，对比招待客人人数少的
                if (consumerNum > chefDuel1StageData.getHighConsumerNum()){
                    chefDuel1StageData.setHighScore(coin);
                    chefDuel1StageData.setHighConsumerNum(consumerNum);
                    userData.setUpdateOption();
                    //极限挑战更新排行榜
                    if (missionConfig.getType() == 0){
                        notifyUnlimitedRank(consumerNum,coin);
                    }
                }else if (consumerNum == chefDuel1StageData.getHighConsumerNum()){
                    if (coin > chefDuel1StageData.getHighScore()){
                        chefDuel1StageData.setHighScore(consumerNum);
                    }
                    userData.setUpdateOption();
                    //极限挑战更新排行榜
                    if (missionConfig.getType() == 0){
                        notifyUnlimitedRank(consumerNum,coin);
                    }
                }
            }

            builder.setRet(0);
            builder.setUserData(parseUserDataToMsg());
            player.sendPacket(ClientProtocol.U_CHEF_DUEL1_GAME_OVER,builder);
            return 0;
        }

        //先设置通关
        addUserPassStage(stageId,coin,consumerNum);
        //普通关卡排行更新
        if (missionConfig.getType() != 0){
            notifyRank();
        }else {
            //极限挑战更新排行榜
            notifyUnlimitedRank(consumerNum,coin);
        }
        builder.setRet(0);
        //配置奖励
        String reward = missionConfig.getReward();
        //玩家加奖励 保险点只有普通模式加 无尽不给东西
        if(missionConfig.getType() != 0){
            player.getModule(CurrencyModule.class).addCurrency(reward,eLogMoneyType.ChefDuel,eLogMoneyType.ChefDuel1PassReward);
        }
        builder.setReward(reward);
        builder.setUserData(parseUserDataToMsg());

        player.sendPacket(ClientProtocol.U_CHEF_DUEL1_GAME_OVER,builder);
        //通关日志 不是无尽才加日志
        LogChefDuelPhase1PassStage logChefDuelPhase1PassStage = new LogChefDuelPhase1PassStage(activityId, getUserId(), stageId, userData.getGrade(), userData.getStringSkill(), 1, coin, reward);
        AutoLogMgr.add(logChefDuelPhase1PassStage);
        return 0;
    }

    /**
     * 开始某一个关卡 type 1是手动通关 2是一键三星通关
     */
    public int startGaming(int activityId,int type,int stageId){
        int checkCanPlayGame = checkCanPlayGame(activityId);
        if (checkCanPlayGame!=0){
            return checkCanPlayGame;
        }
        ChefDuel1Config config = ChefDuelPhase1Mgr.getConfig();
        ChefDuel1MissionConfig missionConfig = config.getMissionConfig(stageId);
        if (missionConfig == null){
            return GameErrorCode.E_CHEF_DUEL1_CONFIG_ERROR;
        }
        Map<Integer, ChefDuel1StageData> passStages = userData.getPassStages();
        //普通关卡的
        if (missionConfig.getType() != 0){
            //如果不是第一关 先检测上一关是不是通关了
            if (stageId != 1){
                int lastStage = stageId - 1;
                synchronized (this){
                    if (!passStages.containsKey(lastStage)){
                        return GameErrorCode.E_CHEF_DUEL1_NO_FINISH_LAST;
                    }
                }
            }
        }else { //极限挑战
            //如果没有通过特定的关卡
            if (!passStages.containsKey(config.getEndlessUnlockStage())){
                return GameErrorCode.E_CHEF_DUEL1_NO_FINISH_LAST;
            }
        }



        //看看是不是到达了积分限制
        if (userData.getGrade() < missionConfig.getScoreLimit()){
            return GameErrorCode.E_CHEF_DUEL1_GRADE_NO_ENOUGH;
        }
        //自己手动打
        if (type == 1){
            playingStageId = stageId;
            ChefDuelPhase1Proto.ChefDuelPhase1StartGameResp.Builder resp = ChefDuelPhase1Proto.ChefDuelPhase1StartGameResp.newBuilder();
            resp.setRet(0);
            player.sendPacket(ClientProtocol.U_CHEF_DUEL1_START_GAMING,resp);
            return 0;
        }else { //一键通关
            //判断是否可以快速通关 如果积分不够
            if (userData.getGrade() < missionConfig.getScorePass()){
                return GameErrorCode.E_CHEF_DUEL1_GRADE_NO_ENOUGH;
            }
            //如果是无限挑战 不能一键通关
            if (missionConfig.getType() == 0){
                return GameErrorCode.E_CHEF_DUEL1_ARG_ERROR;
            }

            //拿关卡
            synchronized (this){
                if (passStages.containsKey(stageId)){
                    return GameErrorCode.E_CHEF_DUEL1_HAS_PASS;
                }
            }
            //设置通关 两个最高是0
            addUserPassStage(stageId,0,0);
            //排行更新
            notifyRank();
            //奖励配置
            String reward = missionConfig.getReward();

            userData.setUpdateOption();
            //加奖励
            player.getModule(CurrencyModule.class).addCurrency(reward,eLogMoneyType.ChefDuel,eLogMoneyType.ChefDuel1PassReward);

            ChefDuelPhase1Proto.ChefDuelPhase1StartGameResp.Builder resp = ChefDuelPhase1Proto.ChefDuelPhase1StartGameResp.newBuilder();
            resp.setRet(0);
            resp.setReward(reward);
            resp.setUserData(parseUserDataToMsg());
            player.sendPacket(ClientProtocol.U_CHEF_DUEL1_START_GAMING,resp);

            //通关日志
            LogChefDuelPhase1PassStage logChefDuelPhase1PassStage = new LogChefDuelPhase1PassStage(activityId, getUserId(), stageId, userData.getGrade(), userData.getStringSkill(), 2, -1, reward);
            AutoLogMgr.add(logChefDuelPhase1PassStage);
            return 0;
        }
    }

    /**
     * 增加玩家的通关数据
     */
    public void addUserPassStage(int stageId,long highScore,int consumer){
        synchronized (this){
            if (userData == null){
                return;
            }
            Map<Integer, ChefDuel1StageData> stageDataMap = userData.getPassStages();
            ChefDuel1StageData chefDuel1StageData = new ChefDuel1StageData(stageId, consumer, highScore);
            stageDataMap.put(stageId, chefDuel1StageData);
            userData.setUpdateOption();
        }
    }

    /**
     * 获取满级的建筑列表
     */
    public List<Integer> getMaxLevelBuilding(ChefDuel1Config config){
        List<Integer> maxLevelBuilding = new ArrayList<>();
        for (ChefDuel1DeviceGroup group:userData.getDeviceDataMap().values()){
            ChefDuel1LevelConfig levelConfig = config.getLevelConfig(group.getLevel());
            //配置没了
            if (levelConfig == null){
                continue;
            }
            //满级了
            if (levelConfig.getExp() <= 0){
                maxLevelBuilding.add(group.getId());
            }
        }
        return maxLevelBuilding;
    }

    /**
     * 开始改造 type1是单次 2是十连(体力不足10的时候有多少用多少)
     */
    public int makeModify(int activityId,int type){
        int checkCanPlayGame = checkCanPlayGame(activityId);
        if (checkCanPlayGame != 0){
            return checkCanPlayGame;
        }
        ChefDuel1Config config = ChefDuelPhase1Mgr.getConfig();

        //先恢复体力
        checkEnergyRecovery();
        //一点体力都没有 直接弹回去
        if (userData.getEnergyNum() <= 0){
            return GameErrorCode.E_CHEF_DUEL1_NO_ENERGY;
        }
        //看看有没有解锁十连
        if (type == 2){
            if (userData.getTotalModifyTime() < config.getTenDrawLimitTimes()){
                return GameErrorCode.E_CHEF_DUEL1_NO_UNLOCK_TEN;
            }
        }
        //实际的抽取次数 type2是十连 1是单次
        int drawTime = 1;
        if (type == 2){
            drawTime = Math.min(userData.getEnergyNum(), 10);
        }
        //随机出设施组id和配置
        List<ChefDuelPhase1Proto.ChefDuelPhase1DrawResult> drawResultBuilds = new ArrayList<>();
        Map<Integer,Integer> deviceGroupAddExp = new HashMap<>();
        Property totalReward = new Property();

        Map<Integer, ChefDuel1DeviceGroup> deviceDataMap = userData.getDeviceDataMap();

        long totalScore = 0;
        //抽drawTime次 一次次抽
        for (int realDraw = 0; realDraw < drawTime; realDraw++){
            //随机一个改造结果出来
            ChefDuel1DrawModifyConfig randomDrawModifyConfig = config.randomDrawModifyConfig();
            //如果是活动第一次抽取 设置特殊的品质
            if (userData.getTotalModifyTime() == 0 && realDraw == 0){
                randomDrawModifyConfig = config.getFirstDrawModifyConfig();
            }
            //如果随机不出来
            if (randomDrawModifyConfig == null){
                log.error("厨神争霸一阶段随即不出改造配置,活动id{}",activityId);
                return GameErrorCode.E_CHEF_DUEL1_CONFIG_ERROR;
            }
            //兑换积分道具获得
            int score = randomDrawModifyConfig.getScore();
            totalScore += score;

            //先获取一下没满级的建筑
            List<Integer> maxLevelBuilding = getMaxLevelBuilding(config);
            //随机一个设备组的id
            int randomDeviceGroupId = config.randomDeviceGroupId(maxLevelBuilding);
            if (randomDeviceGroupId <= 0 || !deviceDataMap.containsKey(randomDeviceGroupId)){
                log.error("厨神争霸一阶段随即不出改造设施,活动id{},玩家id{}",activityId,getUserId());
                return GameErrorCode.E_CHEF_DUEL1_USER_DATA_ERROR;
            }
            //单次奖励
            Property singleReward = new Property(config.getScoreId(),score);

            ChefDuelPhase1Proto.ChefDuelPhase1DrawResult.Builder builder = ChefDuelPhase1Proto.ChefDuelPhase1DrawResult.newBuilder();
            builder.setDeviceGroupId(randomDeviceGroupId);
            builder.setAddExp(randomDrawModifyConfig.getExp());
            String rewardS = PropertyHelper.parsePropertyToString(singleReward);
            builder.setReward(rewardS);
            drawResultBuilds.add(builder.build());
            //汇总奖励
            totalReward.addProperty(singleReward);

            //汇总各个设备组获得的exp
            if (!deviceGroupAddExp.containsKey(randomDeviceGroupId)){
                deviceGroupAddExp.put(randomDeviceGroupId,randomDrawModifyConfig.getExp());
            }else {
                deviceGroupAddExp.put(randomDeviceGroupId,deviceGroupAddExp.get(randomDeviceGroupId)+randomDrawModifyConfig.getExp());
            }
            //改造单次日志
            LogChefDuelPhase1Modify logChefDuelPhase1Modify = new LogChefDuelPhase1Modify(activityId, getUserId(), 1, randomDrawModifyConfig.getNo(), randomDeviceGroupId + "=" + randomDrawModifyConfig.getExp(), randomDrawModifyConfig.getScore());
            AutoLogMgr.add(logChefDuelPhase1Modify);

        }
        //先扣体力
        userData.setEnergyNum(userData.getEnergyNum() - drawTime);
        //加历史次数
        userData.setTotalModifyTime(userData.getTotalModifyTime()+drawTime);
        //保险
        userData.setUpdateOption();
        //加积分
        userData.setScore(userData.getScore()+totalScore);
        //加道具
        player.getModule(CurrencyModule.class).addCurrency(totalReward, eLogMoneyType.ChefDuel,eLogMoneyType.ChefDuel1MakeModify);
        //重新算评分
        recalculateGrade(config);
        //更新积分排行榜 成就
        notifyCondition(userData.getScore());
        notifyRank();

        //回包初始化
        ChefDuelPhase1Proto.ChefDuelPhase1ModifyResp.Builder resp = ChefDuelPhase1Proto.ChefDuelPhase1ModifyResp.newBuilder();
        resp.setRet(0);
        resp.addAllDrawResult(drawResultBuilds);

        for (Map.Entry<Integer,Integer> entry :deviceGroupAddExp.entrySet()){
            //在这给设备组加经验
            ChefDuelPhase1Proto.ChefDuelPhase1DeviceGroupAddExpResult.Builder addExpB = deviceGroupAddExp(config, entry.getKey(), entry.getValue());
            if (addExpB !=null){
                resp.addAddExp(addExpB);
            }
        }


        resp.setUserData(parseUserDataToMsg());
        player.sendPacket(ClientProtocol.U_CHEF_DUEL1_MAKE_MODIFY,resp);
        return 0;
    }

    /**
     * 重算分数
     */
    public long recalculateGrade(ChefDuel1Config config){
        //加积分
        long oldGrade = userData.getGrade();
        long newGrade = 0;
        //菊下楼对决--餐馆评分计算公式（总等级^参数1*灵光点使用数量+参数2*总等级）
        int totalGroupLevel = getTotalGroupLevel();
        long pow = (long)Math.pow(totalGroupLevel, config.getCalGradeParam1());
        newGrade = pow + (long) config.getCalGradeParam2() * totalGroupLevel;

        //更新当前分数
        if (oldGrade != newGrade){
            userData.setGrade(newGrade);
        }
        //如果分比历史最高还高 就要去更新
        if (newGrade > userData.getHighestGrade()){
            //设置历史最高为该值
            userData.setHighestGrade(newGrade);
        }

        return newGrade;
    }

    /**
     * 设备组总等级
     */
    public int getTotalGroupLevel(){
        int totalGroupLevel = 0;
        for (ChefDuel1DeviceGroup deviceGroup:userData.getDeviceDataMap().values()){
            totalGroupLevel += deviceGroup.getLevel();
        }
        return totalGroupLevel;
    }


    /**
     * 设施增加exp
     */
    public ChefDuelPhase1Proto.ChefDuelPhase1DeviceGroupAddExpResult.Builder deviceGroupAddExp(ChefDuel1Config config, int deviceGroupId, int addExp){
        ChefDuel1DeviceGroup deviceGroup = getDeviceGroup(deviceGroupId);
        if (deviceGroup == null){
            log.error("玩家{}抽到设备id{}的设备但是没有设备,经验{},活动id{}",getUserId(),deviceGroupId,addExp,config.getActivityId());
            return null;
        }
        int oldLv = deviceGroup.getLevel();
        int oldExp = deviceGroup.getExp();
        long oldGrade = userData.getGrade();
        int addPoint = 0;

        //先设置总经验
        deviceGroup.setExp(deviceGroup.getExp()+addExp);
        for (int i = 0;i < 100;i++){    //保守循环
            //配置没了
            ChefDuel1LevelConfig levelConfig = config.getLevelConfig(deviceGroup.getLevel());
            if (levelConfig == null){
                break;
            }
            //满级了
            if (levelConfig.getExp() <= 0){
                break;
            }
            //如果可以升级
            if (deviceGroup.getExp() >= levelConfig.getExp()){
                //升一级
                deviceGroup.setLevel(deviceGroup.getLevel()+1);
                //灵光点
                addPoint += levelConfig.getGetTalentPoints();
            }else {
                break;
            }
        }
        if (addPoint > 0){
            //加到设备组记录里
            deviceGroup.setTotalPoint(addPoint);
            //加灵光点到玩家身上
            userData.setTotalGetPoint(userData.getTotalGetPoint()+addPoint);
            userData.setRemainPoint(userData.getRemainPoint()+addPoint);
        }

        int newLv = deviceGroup.getLevel();
        long newGrade = recalculateGrade(config);
        if (oldLv != newLv){
            //升级日志
            LogChefDuelPhase1DeviceGroupLevelUp log = new LogChefDuelPhase1DeviceGroupLevelUp(config.getActivityId(), getUserId(), deviceGroupId, oldLv, newLv, oldGrade, newGrade, addPoint);
            AutoLogMgr.add(log);
        }

        ChefDuelPhase1Proto.ChefDuelPhase1DeviceGroupAddExpResult.Builder builder = ChefDuelPhase1Proto.ChefDuelPhase1DeviceGroupAddExpResult.newBuilder();
        builder.setDeviceGroupId(deviceGroupId);
        builder.setOldLv(oldLv);
        builder.setOldExp(oldExp);
        builder.setAddPoint(addPoint);
        builder.setAddExp(addExp);

        builder.setNewLv(newLv);

        return builder;
    }

    public ChefDuel1DeviceGroup getDeviceGroup(int deviceGroupId){
        return userData.getDeviceDataMap().get(deviceGroupId);
    }


    /**
     * 检测体力回复
     */
    public void checkEnergyRecovery(){
        synchronized (this){
            if (userData == null){
                return;
            }
            ChefDuel1Config config = ChefDuelPhase1Mgr.getConfig();
            if (config == null) {
                return;
            }
            CalcPowerResult calcPowerResult = PowerHelper.calcPower(userData.getLastRecoveryEnergyTime() / 1000, config.getEnergyRecTime(), 1, config.getMaxEnergy(), userData.getEnergyNum());
            userData.setEnergyNum(calcPowerResult.getCurPower());
            userData.setLastRecoveryEnergyTime(calcPowerResult.getLastRecoverTime() * 1000);
        }
    }

    /**
     * 检测是否可以玩游戏 0为可以玩
     */
    public int checkCanPlayGame(int activityId){
        if (!SystemOpenMgr.systemOpen(player,eSystemId.ChefDuelPhase1.getValue())){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        if (userData == null || userData.getActivityId() != activityId){
            checkAndSendData();
            if (userData == null || userData.getActivityId() != activityId){
                return GameErrorCode.E_SYSTEM_NO_OPEN;
            }
        }

        ChefDuel1Config config = ChefDuelPhase1Mgr.getConfig();
        if (config == null) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        //id不对
        if (activityId != config.getActivityId()){
            return GameErrorCode.E_ACTIVITY_NO_JOIN;
        }
        //是不是在开启时间
        if (!ActivityMgr.activityInTime(config.getActivityInfo())){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }
        return 0;
    }



    /**
     * 检测是否生成了玩家数据
     */
    public void checkInitUserData(){
        synchronized (this){
            if(!SystemOpenMgr.systemOpen(player, eSystemId.ChefDuelPhase1.getValue())){
                return;
            }
            ChefDuel1Config config = ChefDuelPhase1Mgr.getConfig();
            if (config == null) {
                return;
            }
            if (!ActivityMgr.activityInShowTime(config.getActivityInfo())){
                return;
            }

            if (userData != null && userData.getActivityId() == config.getActivityId()) {
                return;
            }
            ChefDuelPhase1UserData tmpUserData = new ChefDuelPhase1UserData();
            tmpUserData.setActivityId(config.getActivityId());
            tmpUserData.setUserId(player.getUserId());
            tmpUserData.setEnergyNum(config.getInitEnergy());
            tmpUserData.setLastRecoveryEnergyTime(System.currentTimeMillis());
            Map<Integer, ChefDuel1DeviceGroup> initDeviceDataMap = config.getInitDeviceDataMap();
            if (initDeviceDataMap == null) {
                log.error("配置的初始设备组数据有误 初始化玩家厨神一阶段数据失败 userId:{},activityId{}",getUserId(), config.getActivityId());
                return;
            }
            tmpUserData.setDeviceDataMap(initDeviceDataMap);
            tmpUserData.setRemainPoint(0);
            tmpUserData.setTotalGetPoint(0);
            tmpUserData.setSkill(new ConcurrentHashMap<>());
            tmpUserData.setGrade(0);
            tmpUserData.setPassStages(new ConcurrentHashMap<>());
            tmpUserData.setTotalModifyTime(0);
            tmpUserData.setHighestGrade(0);
            tmpUserData.setScore(0);
            tmpUserData.setInsertOption();
            userData = tmpUserData;
        }
    }



    /**
     * 同步配置
     */
    public void syncConfig(){
        ChefDuel1Config config = ChefDuelPhase1Mgr.getConfig();
        if (config != null) {
            ChefDuelPhase1Proto.ChefDuelPhase1ActivityMsgSync.Builder builder = ChefDuelPhase1Mgr.getParse1ConfigMsg( player.getLanguage());
            if (builder != null) {
                player.sendPacket(ClientProtocol.U_CHEF_DUEL1_SYNC_CONFIG, builder);
            }
        }
    }


    /**
     *  同步玩家数据
     */
    public void syncUserData(){
        if (userData != null) {
            ChefDuelPhase1Proto.ChefDuelPhase1UserData.Builder builder = parseUserDataToMsg();
            if (builder != null) {
                ChefDuelPhase1Proto.ChefDuelPhase1SyncUserDataMsg.Builder newBuilder = ChefDuelPhase1Proto.ChefDuelPhase1SyncUserDataMsg.newBuilder();
                newBuilder.setData(builder);
                player.sendPacket(ClientProtocol.U_CHEF_DUEL1_USER_DATA_SYNC, newBuilder);
            }
        }
    }

    /**
     * 加体力
     */
    public int addEnergy(int activityId,int useNum){
        int checkCanPlayGame = checkCanPlayGame(activityId);
        if (checkCanPlayGame != 0){
            return checkCanPlayGame;
        }
        //配置
        ChefDuel1Config config = ChefDuelPhase1Mgr.getConfig();
        int energyItemId = config.getEnergyItemId();
        GoodsInfo goodsById = GoodsMgr.getGoodsById(energyItemId);
        if (goodsById == null) {
            return GameErrorCode.E_CHEF_DUEL1_CONFIG_ERROR;
        }
        //先自然回复一次
        checkEnergyRecovery();
        int recoveryPerItem = goodsById.getParamList().get(0).intValue();
        Property cost = new Property(energyItemId, useNum);
        if (!player.getModule(CurrencyModule.class).removeCurrency(cost,eLogMoneyType.ChefDuel,eLogMoneyType.ChefDuel1AddEnergy)) {
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }
        userData.setEnergyNum(userData.getEnergyNum() + recoveryPerItem * useNum);
        ChefDuelPhase1Proto.ChefDuelPhase1AddEnergyResp.Builder resp = ChefDuelPhase1Proto.ChefDuelPhase1AddEnergyResp.newBuilder();
        resp.setRet(0);
        resp.setUserData(parseUserDataToMsg());
        player.sendPacket(ClientProtocol.U_CHEF_DUEL1_ADD_ENERGY, resp);
        return 0;
    }

    /**
     * 洗点 重置技能
     */
    public int resetSkillPoint(int activityId){
        int checkCanPlayGame = checkCanPlayGame(activityId);
        if (checkCanPlayGame != 0){
            return checkCanPlayGame;
        }
        int oldPoint = userData.getRemainPoint();
        long oldGrade = userData.getGrade();
        //配置
        ChefDuel1Config config = ChefDuelPhase1Mgr.getConfig();
        String resetSkillCost = config.getResetSkillCost();
        Property cost = PropertyHelper.parseStringToProperty(resetSkillCost);
        if (cost.isNothing()){
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }
        //不用洗点的情况
        if (userData.getTotalGetPoint() == 0 || userData.getTotalGetPoint() == userData.getRemainPoint()){
            return GameErrorCode.E_CHEF_DUEL1_NO_NEED_RESET_SKILL;
        }
        //先扣道具
        if (!player.getModule(CurrencyModule.class).removeCurrency(cost,eLogMoneyType.ChefDuel,eLogMoneyType.ChefDuel1ResetSkill)){
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }
        //重置技能
        userData.setSkill(new ConcurrentHashMap<>());
        //恢复技能点
        userData.setRemainPoint(userData.getTotalGetPoint());
        //刷新分数
//        long newScore = recalculateGrade(config);

        ChefDuelPhase1Proto.ChefDuelPhase1RemakeSkillResp.Builder builder = ChefDuelPhase1Proto.ChefDuelPhase1RemakeSkillResp.newBuilder();
        builder.setRet(0);
        builder.setUserData(parseUserDataToMsg());
        player.sendPacket(ClientProtocol.U_CHEF_DUEL1_SKILL_REMAKE, builder);

        LogChefDuelPhase1Skill skillLog = new LogChefDuelPhase1Skill(activityId, getUserId(), 0, 2, oldPoint, userData.getRemainPoint(), oldGrade, oldGrade);
        AutoLogMgr.add(skillLog);
        return 0;
    }


    /**
     * 升级技能
     */
    public int upgradeSkill(int activityId,int skillId){
        int checkCanPlayGame = checkCanPlayGame(activityId);
        if (checkCanPlayGame != 0){
            return checkCanPlayGame;
        }
        ChefDuel1Config config = ChefDuelPhase1Mgr.getConfig();
        ChefDuel1TalentConfig talentConfig = config.getTalentConfig(skillId);
        if (talentConfig == null) {
            return GameErrorCode.E_CHEF_DUEL1_ARG_ERROR;
        }
        Map<Integer, Integer> userSkillMap = userData.getSkill();
        if(userSkillMap == null){
            userData.setSkill(new ConcurrentHashMap<>());
            userSkillMap = userData.getSkill();
        }
        //如果技能到了最高等级 不给升级了
        if (userSkillMap.containsKey(skillId)){
            if (userSkillMap.get(skillId) >= talentConfig.getMaxLevel()){
                return GameErrorCode.E_CHEF_DUEL1_SKILL_MAX;
            }
        }
        //看看前置条件有没有
        List<Integer> unlockTalentsList = talentConfig.getUnlockTalentsList();
        for (int needTalent : unlockTalentsList){
            if (needTalent == 0){
                continue;
            }
            //如果前置条件没满足
            if (!userSkillMap.containsKey(needTalent) || userSkillMap.get(needTalent) <= 0){
                return GameErrorCode.E_CHEF_DUEL1_SKILL_NO_UNLOCK;
            }
        }
        //技能点没了
        if (userData.getRemainPoint() < talentConfig.getConsume()){
            return GameErrorCode.E_CHEF_DUEL1_SKILL_POINT_NO_ENOUGH;
        }
        long oldGrade = userData.getGrade();

        //扣点数
        userData.setRemainPoint(userData.getRemainPoint() - talentConfig.getConsume());
        int oldLv = 0;
        int newLv = 0;
        //加一级
        if (!userSkillMap.containsKey(skillId)){
            userSkillMap.put(skillId, 1);
            newLv = 1;
        }else {
            oldLv = userSkillMap.get(skillId);
            userSkillMap.put(skillId, oldLv + 1);
            newLv = oldLv + 1;
        }
        //刷新分数
//        long newScore = recalculateGrade(config);

        ChefDuelPhase1Proto.ChefDuelPhase1UpgradeSkillResp.Builder builder = ChefDuelPhase1Proto.ChefDuelPhase1UpgradeSkillResp.newBuilder();
        builder.setRet(0);
        builder.setUserData(parseUserDataToMsg());
        player.sendPacket(ClientProtocol.U_CHEF_DUEL1_SKILL_UPGRADE,builder);
        //技能加点日志
        LogChefDuelPhase1Skill skillLog = new LogChefDuelPhase1Skill(activityId, getUserId(), skillId, 1, oldLv, newLv, oldGrade, oldGrade);
        AutoLogMgr.add(skillLog);
        return 0;

    }

    //----------------玩家数据转msg------------------------
    public ChefDuelPhase1Proto.ChefDuelPhase1UserData.Builder parseUserDataToMsg() {
        if (userData == null) {
            return null;
        }
        ChefDuelPhase1Proto.ChefDuelPhase1UserData.Builder builder = ChefDuelPhase1Proto.ChefDuelPhase1UserData.newBuilder();
        builder.setEnergyNum(userData.getEnergyNum());
        builder.setLastRecoveryEnergyTime(userData.getLastRecoveryEnergyTime());
        //设备数据
        for (ChefDuel1DeviceGroup chefDuel1DeviceGroup :userData.getDeviceDataMap().values()){
            ChefDuelPhase1Proto.ChefDuelPhase1DeviceGroupData.Builder deviceBuild = ChefDuelPhase1Proto.ChefDuelPhase1DeviceGroupData.newBuilder();
            deviceBuild.setId(chefDuel1DeviceGroup.getId());
            deviceBuild.setExp(chefDuel1DeviceGroup.getExp());
            deviceBuild.setLevel(chefDuel1DeviceGroup.getLevel());
            deviceBuild.setTotalPoint(chefDuel1DeviceGroup.getTotalPoint());
            builder.addDeviceData(deviceBuild);
        }
        //剩余灵感点
        builder.setRemainPoint(userData.getRemainPoint());
        //总获得灵感点
        builder.setHistoryTotalPoint(userData.getTotalGetPoint());
        //技能
        for (Map.Entry<Integer,Integer> entry:userData.getSkill().entrySet()){
            ChefDuelPhase1Proto.ChefDuelPhase1SkillData.Builder skillBuild = ChefDuelPhase1Proto.ChefDuelPhase1SkillData.newBuilder();
            skillBuild.setSkillId(entry.getKey());
            skillBuild.setLv(entry.getValue());
            builder.addSkills(skillBuild);
        }

        for (ChefDuel1StageData stageData:userData.getPassStages().values()){
            ChefDuelPhase1Proto.ChefDuelPhase1PassStageData.Builder stageB = ChefDuelPhase1Proto.ChefDuelPhase1PassStageData.newBuilder();
            stageB.setStageId(stageData.getStageId());
            stageB.setScore(stageData.getHighScore());
            stageB.setCustomerNum(stageData.getHighConsumerNum());
            builder.addPassStageData(stageB);
        }

        builder.setTotalModifyTime(userData.getTotalModifyTime());
        builder.setScore(userData.getScore());
        builder.setGrade(userData.getGrade());
        return builder;
    }

    /**
     * 获取玩家最大关卡是哪个
     */
    public int getMaxStage(){
        if (userData == null) {
            log.error("没有玩家数据但是去取最大关卡了,有问题,userId{}",getUserId());
            return 0;
        }
        int maxStageId = 0;
        for (ChefDuel1StageData data:userData.getPassStages().values()){
            if (data.getStageId()> maxStageId){
                maxStageId = data.getStageId();
            }
        }
        return maxStageId;
    }

    /**
     * 更新一下排行榜
     */
    public void notifyRank(){
        if (userData ==null){
            return;
        }
        ChefDuel1Config config = ChefDuelPhase1Mgr.getConfig();
        if (config == null) {
            return;
        }
        //不在时间内的干掉
        if (!ActivityMgr.activityInTime(config.getActivityInfo())){
            return;
        }
        //更新
        player.notifyListener(eGamePlayerEventType.ChefDuel1StageScoreRank.getValue(),new ChefDuel1RankArg(getMaxStage(),userData.getScore()));
    }

    /**
     * 更新一下condition
     */
    public void notifyCondition(long score){
        player.notifyListener(eGamePlayerEventType.ChefDuel1ScoreCondition.getValue(),score);
    }

    /**
     * 更新一下极限挑战排行榜
     */
    public void notifyUnlimitedRank(int guest,long coin){
        if (userData ==null){
            return;
        }
        ChefDuel1Config config = ChefDuelPhase1Mgr.getConfig();
        if (config == null) {
            return;
        }
        //不在时间内的干掉
        if (!ActivityMgr.activityInTime(config.getActivityInfo())){
            return;
        }
        //更新
        player.notifyListener(eGamePlayerEventType.ChefDuelPhase1UnlimitedRank.getValue(),new ChefDuel1UnlimitedRankArg(guest,coin));

    }


}
